package com.shihan.rabbitmq;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.concurrent.TimeoutException;

/**
 * @Description 死信队列
 * @Author shihan
 * @Date 2021/1/9 20:11
 * @Version 1.0
 */
public class DeadLetterQueueProducer {
    // 正常的业务队列、交换器、路由key
    public static final String QUEUE_NAME_BIZ = "queue.name.biz";
    public static final String EXCHANGE_NAME_BIZ = "exc.name.biz";
    public static final String BINDING_KEY_BIZ = "key.biz";

    // 死信队列，是逻辑上的定义，就是拿一个普通队列来实现的
    public static final String QUEUE_NAME_DLQ = "queue.name.dlq";
    public static final String EXCHANGE_NAME_DLQ = "exc.name.dlq";
    public static final String BINDING_KEY_DLQ = "key.dlq";

    public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, URISyntaxException, IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setUri("amqp://root:123456@192.168.66.129/%2f");

        /**
         * 将指定资源放在 try 的内部时，在 try catch 结束后，这些资源就将被释放！
         */
        try (
                Connection connection = connectionFactory.newConnection();
                Channel channel = connection.createChannel();) {

            // 一、声明定义 死信队列、死信交换器、对应的 Binding key
            channel.queueDeclare(QUEUE_NAME_DLQ, true, false, false, null);
            channel.exchangeDeclare(EXCHANGE_NAME_DLQ, BuiltinExchangeType.DIRECT, true);
            channel.queueBind(QUEUE_NAME_DLQ, EXCHANGE_NAME_DLQ, BINDING_KEY_DLQ);

            // 二、当前 Queue 与 死信队列 相关的参数设置 Map
            HashMap<String, Object> queueArguments = new HashMap<>();
            // 消息队列中的消息，过期时间为 10 秒！
            queueArguments.put("x-message-ttl", 10 * 1000);
            // 给当前队列添加 死信交换器 的配置
            queueArguments.put("x-dead-letter-exchange", EXCHANGE_NAME_DLQ);
            // 给当前队列添加，往 死信交换器 发送消息时对应的 Routing Key
            queueArguments.put("x-dead-letter-routing-key", BINDING_KEY_DLQ);

            // 三、照常声明队列
            channel.queueDeclare(QUEUE_NAME_BIZ, true, false, false, queueArguments);

            channel.exchangeDeclare(EXCHANGE_NAME_BIZ, BuiltinExchangeType.DIRECT, true);

            channel.queueBind(QUEUE_NAME_BIZ, EXCHANGE_NAME_BIZ, BINDING_KEY_BIZ);

            AMQP.BasicProperties basicProperties = new AMQP.BasicProperties.Builder()
                    .contentEncoding("utf-8")
                    .deliveryMode(2)    // deliveryMode = 2 表示持久化！
                    .build();
            channel.basicPublish(EXCHANGE_NAME_BIZ, BINDING_KEY_BIZ, basicProperties, "测试死信队列的消息！".getBytes("utf-8"));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

        }

    }

}
